import core.util.Iterator;

/**
 * The ordered collection (actually it's a list) of unique elements.
 */
class OrderedSet {

    /**
     * @public
     * @constructor
     */
    this.OrderedSet = function() {
        this.elements = [];
    };

    /**
     * Adds new element to the collection.
     *
     * @param element (variant) The element to add.
     */
    this.add = function(element) {
        if (!this.contains(element)) {
            this.elements = this.elements.slice(); // Copy on write
            this.elements.push(element);
        }
    };

    /**
     * Removes element from the list.
     *
     * @param element (variant) The element to remove.
     */
    this.remove = function(element) {
        var i = this.indexOf(element);
        if (i >= 0) {
            this.elements = this.elements.slice(); // Copy on write
            delete this.elements[i];
            this.elements.splice(i, 1);
        }
    };

    /**
     * Removes all elements from the collection.
     */
    this.clear = function() {
        this.elements.length = 0;
    };

    /**
     * Checks whether the collection has the specified element.
     *
     * @param element (variant) The element to check.
     */
    this.contains = function(element) {
        return this.elements.indexOf(element) >= 0;
    };

    /**
     * Returts index of element in the collection.
     *
     * @param element (variant) The element to find.
     * @return int
     */
    this.indexOf = function(element) {
        return this.elements.indexOf(element);
    };

    /**
     * Returns the size of collection.
     *
     * @return int
     */
    this.size = function() {
        return this.elements.length;
    };

    /**
     * Returns the iterator over this collection.
     *
     * @return Iterator
     */
    this.iterator = function() {
        return new Iterator(this.elements);
    };

    /**
     * Returns the native JavaScript array containing elements of the ordered set.
     *
     * @return array
     */
    this.toArray = function() {
        return this.elements;
    };
}